#ifndef ENGINE_BACKBONE_H
#define ENGINE_BACKBONE_H


#include "SDL.h"
#include <cstdlib>
#include <list>
#include <string>
#include <map>

namespace Engine { class Visual; } 
namespace Engine { class Reason; } 
namespace Engine { class Sense; } 
namespace Engine { class Renderer; } 

namespace Engine {

// Dispatch events (including tick/update) to listeners
// Notify of rendering
class Backbone {
  private:
    enum BackboneStatus {
    	BACKBONE_DEAD = 0,//Not yet initialized
    	BACKBONE_SLEEPING,// initialized, awaiting to be pulsen
    	BACKBONE_AWAKEN

    };

    // Each context have its own senses, reasons and visuals, and probably something else.
    class Context {
      public:
    	Context(); 
    	virtual ~Context(); 
    	std::list<Visual *> visuals; 
    	std::list<Reason *> reasons; 
    	std::list<Sense *> senses; 
    };
    

  public:
	static bool raise() throw(char *); 
	static void awake(); 
	static void addSense(Sense * sense, std::string contextName = ""); //Add a new sense to a given context or the actual context
	static void dropSense(Sense * sense, std::string contextName = ""); 
	static void addReason(Reason * reason, std::string contextName = ""); 
	static void dropReason(Reason * reason, std::string contextName = ""); 
	static void addVisual(Visual * visual, std::string contextName = ""); 
	static void dropVisual(Visual * visual, std::string contextName = ""); 
	static void changeContext(std::string contextName); // Loads the selected context.

  private:
	static void update(SDL_Event * event); 
	Backbone(); 
	virtual ~Backbone(); 
	static BackboneStatus status; 
	static std::map<std::string, Context> context; 
	static Context * actualContext; 
	static Context * nextContext; // Context to be loaded on the next frame
};

} // namespace Engine
#endif
